package van.planifolia.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import van.planifolia.dao.UserMapper;
import van.planifolia.pojo.MyUser;
import van.planifolia.pojo.Permission;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description: TODO: 用户的业务层
 * @Author: Van.Planifolia
 * @CreateTime: 2023-01-03  10:34
 * @Version: 1.0
 */
@Service("userService")
public class UserService implements UserDetailsService {

    @Resource(name = "userMapper")
    private UserMapper userMapper;

    /**
     * 自定义的用户身份验证
     *
     * @param username 用户名
     * @return 封装好的用户信息
     * @throws UsernameNotFoundException 用户名字未找到
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 首先我们要根据用户的名字查询用户的信息确保当前这个用户他存在
        MyUser userInfo = userMapper.selectOne(new QueryWrapper<MyUser>().eq("username", username));
        // 当确实拥有这个用户信息的时候，我们在进行进一步的授权操作
        if (userInfo != null) {
            // 当确定有这个人了我们就要给这个人上权限了，那么权限从那里来当然也是根据数据库进行的查询
            // 这里就根据用户的id查询到了用户的权限
            List<Permission> permissions = userMapper.selectPerByUid(userInfo.getUserid());
            // 下面我们就要吧用户的信息return出去,我们需要Return的类型为UserDetails，但是他是一个接口，所以我们
            // 只能返回他的实现类User,但是他最后一个的权限信息需要的是一个 Collection<? extends GrantedAuthority> authorities
            // 所以我们就要吧原本查询出来的permissions处理一下,然后我们将处理过的List放入User的构造方法中发现就不会报错了
            List<SimpleGrantedAuthority> authorities = permissions.stream().map(e -> new SimpleGrantedAuthority(e.getPercode())).collect(Collectors.toList());
            // 最终我们返回处理好的用户对象，剩下的就是交给SpringSecurity进行密码校验了
            return new User(userInfo.getUsername(), userInfo.getUserpwd(), authorities);
        } else {
            throw new RuntimeException("找不到用户");
        }
    }
}
